package com.hd.trans.utils

import android.util.Base64
import android.util.Log
import java.io.File
import java.io.RandomAccessFile


object FileTranslationUtil {
    const val SPLIT_MAX_SIZE = 1L * 1024 * 1024
    private val SUFFIX_ARRAY = arrayOf<String>(
        "txt","doc","docx","ppt","pptx","pdf","xls","xlsx","jpg","png","jpeg","webp")

    /**
     * 传入文档路径，或文档后缀，如：png或.png
     */
    fun isSupportedFormat(filePath: String): Boolean{
        return SUFFIX_ARRAY.contains(File(filePath).extension.toLowerCase())
                || SUFFIX_ARRAY.contains(filePath.replace(".","").toLowerCase())
    }

    fun isTxt(filePath: String):Boolean{
        return "txt" == File(filePath).extension.toLowerCase()
                || "txt" == filePath.toLowerCase()
                || ".txt" == filePath.toLowerCase()
    }

    /**
     * 判断文档是否需要分片处理
     */
    fun isFileNeedSharded(filePath: String): Boolean{
        val file = File(filePath)
        if(!file.exists()){
            return true
        }
        return file.length() >= SPLIT_MAX_SIZE
    }

    /**
     * 文档的Base64数据分片处理
     */
    fun splitFile2Base64(file: File): ArrayList<String> {
        val result = ArrayList<String>()
        var offSet = 0L //初始化偏移量
        var input: RandomAccessFile? = null
        try {
            input = RandomAccessFile(file, "r")
            val length = input.length() //文件的总长度
            val count: Int = (length / SPLIT_MAX_SIZE).toInt()
            val base64Head = Base64Util.getBase64Head(file)

            for (i in 0 until count - 1) { //最后一片单独处理
                val begin = offSet
                val end = (i + 1) * SPLIT_MAX_SIZE
                offSet = getRead(input, base64Head, begin, end, result)
            }
            if (length - offSet > 0) {
                getRead(input, base64Head, offSet, length, result)
            }

        }catch (e: Throwable) {
            e.printStackTrace()
        } finally {
            try {
                input?.close()
            } catch (e: Throwable) {
                Log.e("TAG", "getWrite: ", e)
            }
        }
        return result
    }

    private fun getRead(
        input: RandomAccessFile,
        base64Head: String,
        begin: Long,
        end: Long,
        list: ArrayList<String>,
    ): Long {

        var endPointer = 0L
        //申明具体每一文件的字节数组
        val b = ByteArray(1024)
        var outByte = ByteArray(0)
        var n = 0
        //从指定位置读取文件字节流
        input.seek(begin)
        //判断文件流读取的边界
        while (input.filePointer <= end && input.read(b).also { n = it } != -1) {
            outByte = mergeArray(outByte, b.copyOf(n))
        }
        var result = Base64.encodeToString(outByte, Base64.DEFAULT)
        //jdk7中加密/解密带换行符；jdk8中则没有
        result = result?.replace("\n","")?.replace("\r","")
        list.add("${base64Head}$result")
        //定义当前读取文件的指针
        endPointer = input.filePointer

        return endPointer
    }


    /**
     * 合并数组
     */
    private fun mergeArray(first: ByteArray, second: ByteArray): ByteArray {
        val result = first.copyOf(first.size + second.size)
        System.arraycopy(second, 0, result, first.size, second.size)
        return result
    }


    suspend fun splitFile(file: File): ArrayList<File> {
        val result = ArrayList<File>()
        var input: RandomAccessFile? = null
        try {
            input = RandomAccessFile(file, "r")
            val length = input.length() //文件的总长度
            val count: Int = (length / SPLIT_MAX_SIZE).toInt()
            var offSet = 0L //初始化偏移量

            for (i in 0 until count - 1) { //最后一片单独处理
                val begin = offSet
                val end = (i + 1) * SPLIT_MAX_SIZE
                offSet = getWrite(file, i, begin, end, result)
            }
            if (length - offSet > 0) {
                getWrite(file, count - 1, offSet, length, result)
            }
        } finally {
            try {
                input?.close()
            } catch (e: Throwable) {
                Log.e("TAG", "splitFile: ", e)
            }
        }
        return result
    }

    private fun getWrite(
        file: File,
        index: Int,
        begin: Long,
        end: Long,
        list: ArrayList<File>,
    ): Long {

        val tempFileName = FileUtilsKotlin.getSplitTempFilePath(file, index)
        var endPointer = 0L

        var input: RandomAccessFile? = null
        var output: RandomAccessFile? = null

        try {
            input = RandomAccessFile(file, "r")
            val tempFile = File(tempFileName)
            output = RandomAccessFile(tempFile, "rw")
            //申明具体每一文件的字节数组
            val b = ByteArray(1024)
            var n = 0
            //从指定位置读取文件字节流
            input.seek(begin)
            //判断文件流读取的边界
            while (input.filePointer <= end && input.read(b).also { n = it } != -1) {
                //从指定每一份文件的范围，写入不同的文件
                output.write(b, 0, n)
            }

            list.add(tempFile)

            //定义当前读取文件的指针
            endPointer = input.filePointer

        } catch (e: Throwable) {
            e.printStackTrace()
        } finally {
            try {
                input?.close()
                output?.close()
            } catch (e: Throwable) {
                Log.e("TAG", "getWrite: ", e)
            }
        }
        return endPointer
    }
}